package com.xiaomengkuan.product.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xiaomengkuan.common.entity.vo.PageVo;
import com.xiaomengkuan.common.exception.RequestBodyArgumentException;
import com.xiaomengkuan.common.util.DetailSelector;
import com.xiaomengkuan.common.util.R;
import com.xiaomengkuan.product.entity.pojo.Product;
import com.xiaomengkuan.product.entity.pojo.ProductTagRelation;
import com.xiaomengkuan.product.entity.pojo.Tag;
import com.xiaomengkuan.product.entity.pojo.UserProductRelation;
import com.xiaomengkuan.product.entity.tdo.TDO;
import com.xiaomengkuan.product.entity.vo.ProductResponseVo;
import com.xiaomengkuan.product.mapper.ProductMapper;
import com.xiaomengkuan.product.mapper.ProductTagRelationMapper;
import com.xiaomengkuan.product.mapper.TagMapper;
import com.xiaomengkuan.product.mapper.UserProductRelationMapper;
import com.xiaomengkuan.product.remote.UserRemoteService;
import com.xiaomengkuan.product.service.LikeAndFavouriteService;
import com.xiaomengkuan.product.util.RelationSelector;
import org.springframework.beans.BeanUtils;
import org.springframework.boot.actuate.autoconfigure.endpoint.condition.ConditionalOnAvailableEndpoint;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static com.xiaomengkuan.common.util.YsjUtil.*;

/**
 * @author Faraj Mujey
 * -- Creation Time: 2021-01-27 1:37 下午, File Encoding: utf8 --
 */
@Service
public class LikeAndFavouriteServiceImpl implements LikeAndFavouriteService {

    @Resource
    private ProductMapper productMapper;

    @Resource
    private UserProductRelationMapper userProductRelationMapper;

    @Resource
    private UserRemoteService userRemoteService;

    @Resource
    private ProductTagRelationMapper productTagRelationMapper;

    @Resource
    private TagMapper tagMapper;

    /**
     * 喜欢某件商品
     *
     * @param userId    用户id
     * @param productId 商品id
     * @return R
     */
    @Override
    @Transactional
    public TDO like(String userId, String productId, int type) {
        TDO r = new TDO();
        // 确认商品确实存在
        Product product = productMapper.selectById(productId);
        // 确认用户是否存在
        R exist = userRemoteService.isExist(userId);
        if (product != null && exist.getCode() == 200) {
            Date now = new Date();
            // 在商品用户关系表中添加一条喜欢的数据
            UserProductRelation userProductRelation = new UserProductRelation();
            userProductRelation.setCreated_time(now);
            userProductRelation.setProductId(productId);
            userProductRelation.setUserId(userId);
            userProductRelation.setDeleted(0);
            userProductRelation.setRelation(type);
            List<UserProductRelation> relations = userProductRelationMapper.selectList(new QueryWrapper<UserProductRelation>()
                    .eq("user_id", userProductRelation.getUserId()).and(w -> {
                        w.eq("product_id", userProductRelation.getProductId()).and(wa -> {
                            wa.eq("relation", userProductRelation.getRelation());
                        });
                    }));
            if (relations.size() == 0 || relations == null) {
                int insert = userProductRelationMapper.insert(userProductRelation);
                if (insert > 0) {
                    if (type == 0)
                        product.setLike(product.getLike() + 1);
                    else
                        product.setFavourite(product.getFavourite() + 1);
                    productMapper.updateById(product);
                    r.setFlag(true);
                    r.setDetail("操作成功");
                } else {
                    r.setFlag(false);
                    r.setDetail(DetailSelector.INSERT_ERROR);
                }
            } else {
                UserProductRelation userProductRelation1 = relations.get(0);
                int deleted = userProductRelation1.getDeleted();
                if (deleted == 0) {
                    r.setFlag(false);
                    r.setDetail("已有记录存在");
                } else {
                    userProductRelation1.setDeleted(0);
                    userProductRelationMapper.updateById(userProductRelation1);
                    if (type == 0)
                        product.setLike(product.getLike() + 1);
                    else
                        product.setFavourite(product.getFavourite() + 1);
                    productMapper.updateById(product);
                    r.setFlag(true);
                    r.setDetail("操作成功");
                }
            }

        } else {
            r.setFlag(false);
            r.setDetail("用户或商品不存在");
        }
        return r;
    }

    /**
     * 不喜欢某件商品
     *
     * @param userId    用户id
     * @param productId 商品id
     * @return R
     */
    @Override
    @Transactional
    public TDO unlike(String userId, String productId, int type) {
        TDO tdo = new TDO();
        // 确认商品是否存在
        Product product = productMapper.selectById(productId);
        // 确认用户是否存在
        R exist = userRemoteService.isExist(userId);
        if (product != null && exist.getCode() == 200) {
            // 获取喜欢的这条记录
            Map<String, Object> allEqMap = new HashMap<>();
            allEqMap.put("product_id", productId);
            allEqMap.put("relation", type);
            allEqMap.put("user_id", userId);
            allEqMap.put("deleted", 0);
            QueryWrapper<UserProductRelation> userProductRelationQueryWrapper = new QueryWrapper<>();
            userProductRelationQueryWrapper.allEq(allEqMap);
            List<UserProductRelation> userProductRelations =
                    userProductRelationMapper.selectList(userProductRelationQueryWrapper);
            if (userProductRelations.size() == 1) {
                UserProductRelation userProductRelation = userProductRelations.get(0);
                // 将deleted设为1
                userProductRelation.setDeleted(1);
                int i = userProductRelationMapper.updateById(userProductRelation);
                if (i > 0) {
                    if (type == 0)
                        product.setLike(product.getLike() - 1);
                    else
                        product.setFavourite(product.getFavourite() - 1);
                    int j = productMapper.updateById(product);
                    if (j > 0) {
                        tdo.setFlag(true);
                        tdo.setDetail("操作成功");
                    } else {
                        tdo.setFlag(false);
                        tdo.setDetail(DetailSelector.UPDATE_ERROR);
                    }
                } else {
                    tdo.setFlag(false);
                    tdo.setDetail(DetailSelector.UPDATE_ERROR);
                }
            } else if (userProductRelations.size() > 1) {
                tdo.setFlag(false);
                tdo.setDetail("存在多条记录，请联系管理员或稍后重试");
            } else {
                tdo.setFlag(false);
                tdo.setDetail("尚未喜欢或收藏，无法取消");
            }
        } else {
            tdo.setFlag(false);
            tdo.setDetail("用户或商品不存在");
        }

        return tdo;
    }

    @Override
    public long favouriteCount(String userId) {
        Map<String, Object> condition = getAllEqCondition(userId);
        return userProductRelationMapper.selectCount(new QueryWrapper<UserProductRelation>().allEq(condition));
    }

    @Override
    public PageVo<ProductResponseVo> getFavourites(Map<String, Object> requestBody) {
        Integer size = (Integer) requestBody.get("size");
        String userId = (String) requestBody.get("userId");
        Integer current = (Integer) requestBody.get("current");
        if (objsCompliant(size, userId, current)) {
            Map<String, Object> condition = getAllEqCondition(userId);
            List<UserProductRelation> userProductRelations = userProductRelationMapper.selectList(new QueryWrapper<UserProductRelation>().allEq(condition));
            if (userProductRelations.size() > 0) {
                List<String> productIds = userProductRelations.stream().map(UserProductRelation::getProductId).collect(Collectors.toList());
                IPage<Product> iPage = new Page<>(current, size);
                IPage<Product> page = productMapper.selectPage(iPage,
                        new QueryWrapper<Product>().in("id", productIds));
                List<ProductResponseVo> product_id = page.getRecords().stream().map(entity -> {
                    ProductResponseVo productResponseVo = new ProductResponseVo();
                    BeanUtils.copyProperties(entity, productResponseVo);
                    List<ProductTagRelation> relations = productTagRelationMapper.selectList(new QueryWrapper<ProductTagRelation>().eq("product_id", entity.getId()));
                    if (relations.size() > 0) {
                        List<String> tagIds = relations.stream().map(ProductTagRelation::getTagId).collect(Collectors.toList());
                        List<Tag> tags = tagMapper.selectBatchIds(tagIds);
                        productResponseVo.setTags(tags);
                    }
                    return productResponseVo;
                }).collect(Collectors.toList());
                return pageFilling(page.getCurrent(), page.getSize(),
                        page.getTotal(), product_id);
            }
            return null;
        } else {
            throw new RequestBodyArgumentException();
        }
    }

    /*
    private methods
     */
    private Map<String, Object> getAllEqCondition(String userId) {
        Map<String, Object> condition = new HashMap<>();
        condition.put("user_id", userId);
        condition.put("relation", RelationSelector.FAVOURITE);
        condition.put("deleted", 0);
        return condition;
    }
}
